package example.util;

import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.SignatureAlgorithm;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.util.*;

@Log4j2
public class JWTUtil {

    public static final SignatureAlgorithm TOKEN_ALG = Jwts.SIG.PS256;

    public static String createToken(String requestPayloadEncryptedBase64String, PGPPrivateKey pgpPrivateKey, String profileId) throws NoSuchAlgorithmException, PGPException {
        String jti = UUID.randomUUID().toString();
        long nowSeconds = System.currentTimeMillis() / 1000;
        String payloadHash = PGPHelper.generateMessageDigest(requestPayloadEncryptedBase64String, "SHA-256");

        // 前面补零
        String kid = StringUtils.leftPad(Long.toHexString(pgpPrivateKey.getKeyID()).toUpperCase(), 16, '0');

        Map<String, Object> header = new HashMap<>();
        header.put("typ", "JWT");
        header.put("kid", kid);
        header.put("alg", TOKEN_ALG.getId());
        header.put("ver", "1.0");
        header.put("key_typ", "PGP");
        // header.put("obo", Collections.singletonList("BEIJING 17 NETWORK TECH API TEST"));
        log.info("JWT header={}", header);

        Map<String, Object> claims = new HashMap<>();
        claims.put("sub", YamlReader.instance.getValueByKey("APIProfileID"));
        claims.put("iat", nowSeconds);
//        claims.put("aud", "baas");
        claims.put("jti", jti);
        claims.put("payload_hash", payloadHash);
        claims.put("payload_hash_alg", "RSASHA256");
        log.info("JWT claims={}", claims);

        JwtBuilder builder = Jwts.builder();
        builder.header().add(header);
        builder.claims().add(claims).setAudience("baas");
        PrivateKey privateKey = new JcaPGPKeyConverter().getPrivateKey(pgpPrivateKey);
        log.info("PrivateKey Base64={}", Base64.getEncoder().encodeToString(privateKey.getEncoded()));
        return builder.signWith(privateKey, TOKEN_ALG).compact();
    }
}
